import cv2
import requests
import base64
from concurrent.futures import ThreadPoolExecutor

from logger import get_logger
from config import config


# 这个东西的存在是因为报警的种类太多了，全塞一块很乱，所以就弄了个接口（Trigger父类）用于实现各种各样的报警触发方式
class AlertTrigger:
    _alert_collect_url = config.alert_collect_url
    _logger = get_logger('nvrpro.alert')
    _threadpool = ThreadPoolExecutor()

    @staticmethod
    def _alert_to_cloud(json):
        def wrapper():
            if not AlertTrigger._alert_collect_url:
                AlertTrigger._logger.warning(f'没有设置报警收集地址，报警信息将不会推送事件[{json["event"]}]')
                return
            warning_msg = f'推送警报信息失败，推送地址为: {AlertTrigger._alert_collect_url}，报警事件为[{json["event"]}]'
            try:
                r = requests.post(AlertTrigger._alert_collect_url, json=json)
                if not r.ok or r.json()['code'] != 0:
                    AlertTrigger._logger.warning(warning_msg)
            except Exception:
                AlertTrigger._logger.warning(warning_msg)
        AlertTrigger._threadpool.submit(wrapper)

    @staticmethod
    def _encode_jpg_image(image):
        return str(base64.b64encode(cv2.imencode('.jpg', image)[1].tobytes()), 'utf-8')

    def __init__(self, event, object, region):
        self.event = event
        self.object = object
        self.region = region

    def _alert(self, objs, image):
        self._alert_to_cloud({
            'event': self.event,
            'object': self.object,
            'region': self.region,
            'information': {obj.id: obj.box for obj in objs},
            'image': {
                'base64': self._encode_jpg_image(image),
                'ext': 'jpg'
            }
        })

    # 可实现多个，调用顺序：enter / leave -> update

    # # 物体进入调用一次
    # def enter(self, obj, objs, image):
    #     pass

    # # 物体退出调用一次
    # def leave(self, obj, objs, image):
    #     pass

    # # 每个推理帧调用一次
    # def update(self, objs, image):
    #     pass
